package scheme.editor;

import interpreter.Interpreter;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextPane;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import parsing.Parser;
import scanning.Scanner;

public class SchemeEditor {

	private JFrame frmSchemeEditor;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					SchemeEditor window = new SchemeEditor();
					window.frmSchemeEditor.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public SchemeEditor() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmSchemeEditor = new JFrame();
		frmSchemeEditor.setTitle("Scheme Editor");
		frmSchemeEditor.setBounds(100, 100, 680, 466);
		frmSchemeEditor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JSplitPane splitPane = new JSplitPane();
		splitPane.setResizeWeight(0.95);
		frmSchemeEditor.getContentPane().add(splitPane, BorderLayout.CENTER);

		JSplitPane editorSplitPane = new JSplitPane();
		editorSplitPane.setResizeWeight(0.7);
		editorSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		splitPane.setLeftComponent(editorSplitPane);

		JScrollPane scrollPane = new JScrollPane();
		editorSplitPane.setLeftComponent(scrollPane);

		final JTextPane codeArea = new JTextPane();
		codeArea.setText("(define * (lambda (a b) (if (= a 0) 0 (+ b (* (+ a -1) b)))))\r\n(define ^ (lambda (a x) (if (= x 0) 1 (* a (^ a (+ x -1))))))\r\n(* 5 16)\r\n(^ 2 10)\r\n");
		scrollPane.setViewportView(codeArea);

		JScrollPane scrollPane_1 = new JScrollPane();
		editorSplitPane.setRightComponent(scrollPane_1);

		final JTextPane outputArea = new JTextPane();
		scrollPane_1.setViewportView(outputArea);

		JButton runButton = new JButton("Run");
		runButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					String code = codeArea.getText().replaceAll("\r", "");
					Parser parser = new Parser(new Scanner(code));
					Interpreter interpreter = new Interpreter(parser);
					StringBuilder output = new StringBuilder();
					while (interpreter.hasNextForm()) {
						Object result = interpreter.evaluateNextForm();
						if (result != null) {
							output.append(result.toString());
							output.append("\n");
						}
					}
					outputArea.setText(output.toString());
				} catch (Scanner.InvalidToken ex) {
					outputArea.setText("Invalid Token '" + ex.getTokenText()
							+ "' at " + ex.getStart());
					SimpleAttributeSet attributeSet = new SimpleAttributeSet();
					StyleConstants.setBackground(attributeSet, Color.ORANGE);
					codeArea.getStyledDocument()
							.setCharacterAttributes(ex.getOffset(),
									ex.getLength(), attributeSet, false);
				} catch (Parser.ParserError ex) {
					String errorMessage = "Parser error: expected "
							+ ex.getExpectedTokenType() + " but was "
							+ ex.getActualTokenType();
					outputArea.setText(errorMessage);
				} catch (RuntimeException ex) {
					outputArea.setText("Error: " + ex.toString());
				}
			}
		});
		splitPane.setRightComponent(runButton);
	}
}
